
/* permission handling */

#include <stdio.h>
#include "perms.h"


long unix_to_fs_perms(int unixmode) {
  long fsmode;
  
  fsmode = 0;
  if (unixmode & ROWN)
    fsmode |= fs_ROWN;
  if (unixmode & ROTH)
    fsmode |= fs_ROTH;
  if (unixmode & WOWN)
    fsmode |= fs_WOWN;
  if (unixmode & WOTH)
    fsmode |= fs_WOTH;
  return(fsmode);
} /* unix_to_fs_perms */


int fs_to_unix_perms(long fsmode, long LoadAddress) {
  int unixmode;
  
  unixmode = 0;
  if (fsmode & fs_ROWN)
    unixmode |= ROWN;
  if (fsmode & fs_ROTH)
    unixmode |= ROTH;
  if (!(fsmode & fs_LCKD)) {
    if (fsmode & fs_WOWN)
      unixmode |= WOWN;
    if (fsmode & fs_WOTH)
      unixmode |= WOTH;
  }

  if (LoadAddress & 0xFFF00000) {
    switch ((LoadAddress >> 8) & 0xFFF) {
      case ft_Obey:
      case ft_Absolute:
      case ft_Module:
      case ft_BASIC:
      case ft_Utility:
      case ft_Command:
        unixmode |= XOWN;
        if (unixmode & ROTH && unixmode & ROWN)
          unixmode |= XOTH;
        break;
      default:
        break;
    }
  } else {
    unixmode |= XOWN;
    if (unixmode & ROTH && unixmode & ROWN)
      unixmode |= XOTH;
  }

  return(unixmode);
} /* fs_to_unix_perms */


int unix_dir_perms(long fsmode) {
  int unixmode;
  
  unixmode = 0;

  unixmode |= ROWN;
  unixmode |= XOWN;
  if (!(fsmode & fs_LCKD)) {
    unixmode |= WOWN;
    if (fsmode & fs_ROTH) {
      unixmode |= ROTH;
      unixmode |= XOTH;
      unixmode |= WOTH;
    }
  }
  return(unixmode);
} /* unix_dir_perms */


int     m1[] = { 1, ROWN, 'r', '-' };
int     m2[] = { 1, WOWN, 'w', '-' };
int     m3[] = { 2, SUID, 's', XOWN, 'x', '-' };
int     m4[] = { 1, RGRP, 'r', '-' };
int     m5[] = { 1, WGRP, 'w', '-' };
int     m6[] = { 2, SGID, 's', XGRP, 'x', '-' };
int     m7[] = { 1, ROTH, 'r', '-' };
int     m8[] = { 1, WOTH, 'w', '-' };
int     m9[] = { 2, STXT, 't', XOTH, 'x', '-' };

int     *m[] = { m1, m2, m3, m4, m5, m6, m7, m8, m9};


static void select(int *pairp, int mode) {
  int n, *ap;

  ap = pairp;
  n = *ap++;
  while (--n >= 0 && (mode & *ap++) == 0)
    ap++;
  printf("%c", *ap);
} /* select */


void pmode(int mode) {
  int **mp;

  for (mp = &m[0]; mp < &m[9];)
    select(*mp++, mode);
} /* pmode */
